package br.com.lucasddaniel.inbuzios.activities;

import java.io.IOException;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import br.com.lucasddaniel.inbuzios.Controller;
import br.com.lucasddaniel.inbuzios.R;
import br.com.lucasddaniel.inbuzios.bean.BluetoothConnector;
import br.com.lucasddaniel.inbuzios.bean.BluetoothConnector.OnDiscoveryListener;
import br.com.lucasddaniel.inbuzios.bean.Device;
import br.com.lucasddaniel.inbuzios.bean.DeviceAdapter;
import br.com.lucasddaniel.inbuzios.dao.ExcessaoBanco;

/**
 * Activity inicial de localização de devices bluetooth.
 * 
 * @author ldsm
 * 
 */
public class EscaneamentoActivity extends Activity implements OnDiscoveryListener {

	public static final String CONNECTION_STRING = "connection_string";
	private final String FALHA_AO_PROCURAR = "Falha ao procurar";
	private final String ERRO = "Erro";
	private final String AO_ACESSAR_O_BANCO = "Ao acessar o banco";
	private final Handler mHandler = new Handler();
	private ListView mDeviceView;
	private ProgressDialog mProgress;
	private BluetoothConnector mConnector; 
	private Activity activity = this;

	private final DeviceAdapter mAdapter = new DeviceAdapter() {
		public View getView( int position, View convertView, ViewGroup parent ) {
			View view = convertView;
			if( view == null ) {
				LayoutInflater vi = LayoutInflater.from( EscaneamentoActivity.this );
				view = vi.inflate( R.layout.device, null );
			}
			Device device = getContainer().get( position );
			String principal = "";
			if( device.getPrincipal() == 1 ) {
				principal = " <====|";
			}
			( ( TextView ) view.findViewById( R.id.name ) ).setText( device.getNome() + principal );
			( ( TextView ) view.findViewById( R.id.address ) ).setText( device.getEndereco() );

			return view;
		}

		public long getItemId( int location ) {
			return ( long ) location;
		}

		public Object getItem( int location ) {
			return getContainer().get( location );
		}

		public int getCount() {
			return getContainer().size();
		}
	};

	@Override
	public void onCreate( Bundle savedInstanceState ) {
		super.onCreate( savedInstanceState );
		setContentView( R.layout.devices );

		mDeviceView = ( ListView ) findViewById( R.id.devices );
		mDeviceView.setAdapter( mAdapter );
		mDeviceView.setOnItemClickListener( new OnItemClickListener() {

			public void onItemClick( AdapterView<?> parent, View view, int position, long id ) {
				Device device = ( Device ) mAdapter.getItem( position );
				device.setPrincipal( 1 );
				TextView tv = ( TextView ) view.findViewById( R.id.name );
				tv.setText( tv.getText().toString() + " <====|" );

				try {
					Controller.getInstance().atualizarDevice( device, getApplicationContext() );

				} catch( ExcessaoBanco e ) {
					notificarUsuario( ERRO, e.getMessage() );
				}
				finish();
				// Intent data = new Intent( Escaneamento.this, Principal.class );
				// String connectionString = "bth://" + device.getEndereco();
				// data.putExtra( CONNECTION_STRING, connectionString );
				// startActivityForResult( data, 0 );
			}
		} );

		// inicia o bluetooth no sistema operacional caso esteja desligado.
		try {
			Intent enableBtIntent = new Intent( BluetoothAdapter.ACTION_REQUEST_ENABLE );
			startActivityForResult( enableBtIntent, 1 );
			mConnector = BluetoothConnector.getConnector( this );
		} catch( IOException e ) {
			Toast.makeText( this, e.getMessage(), Toast.LENGTH_SHORT ).show();
			finish();
		}
		Button btnPesqImpr = ( Button ) findViewById( R.id.pesqimpr );
		btnPesqImpr.setOnClickListener( new View.OnClickListener() {
			public void onClick( View v ) {
				startDiscovery();
			}
		} );
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
	}

	@Override
	protected void onStart() {
		super.onStart();
		try {
			mAdapter.clear();
			Controller.getInstance().listarDevices( mAdapter, getApplicationContext() );

			mAdapter.notifyDataSetChanged();
		} catch( ExcessaoBanco e ) {
			notificarUsuario( ERRO, AO_ACESSAR_O_BANCO );
		}
	}

	@Override
	protected void onStop() {
		super.onStop();
		try {
			// deleta todos os devices para inserir os novos do escaneamento.
			Controller.getInstance().deletarDevices( getApplicationContext() );
			Controller.getInstance().inserirTodosDevices( mAdapter, getApplicationContext()  );

		} catch( ExcessaoBanco e ) {
			notificarUsuario( ERRO, AO_ACESSAR_O_BANCO );
		}
	}

	private void startDiscovery() {
		try {
			mConnector.startDiscovery( this );
		} catch( IOException e ) {
			notificarUsuario( ERRO, FALHA_AO_PROCURAR );
		}
	}

	/**
	 * Exibe uma mensagem ao usuario de acordo com os parametros passados.
	 * Usada em excessoes.
	 * 
	 * @param titulo
	 * @param message
	 */
	protected void notificarUsuario( final String titulo, final String message ) {
		mHandler.post( new Runnable() {
			public void run() {
				new AlertDialog.Builder( EscaneamentoActivity.this )
						.setTitle( titulo )
						.setMessage( message )
						.create()
						.show();
			}
		} );
	}

	public void onDeviceFound( final String name, final String address ) {
		mHandler.post( new Runnable() {
			public void run() {
				Device device = new Device( name, address );
				if( name == null ) {
					device = new Device( getString( R.string.scan_unknown_device ), address );
				} else {
					device = new Device( name, address );
				}
				mAdapter.add( device );
				mAdapter.notifyDataSetChanged();
			}
		} );
	}

	public void onDiscoveryFinished() {
		mHandler.post( new Runnable() {
			public void run() {
				mProgress.dismiss();
			}
		} );
	}

	public void onDiscoveryStarted() {
		mHandler.post( new Runnable() {
			public void run() {
				mAdapter.clear();
				mAdapter.notifyDataSetChanged();
				mProgress = ProgressDialog.show( EscaneamentoActivity.this, "Aguarde", "Escaneando...", true );
			}
		} );
	}

	public void onDiscoveryError( String error ) {
		notificarUsuario( ERRO, FALHA_AO_PROCURAR );
	}
}